Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit ea761bf1ef757587e0a411b33c27f7f97ebb1fad


Parents : 64a6f06
Author : Mark Qvist <bc7291552be7a58f361522990465165c>
Signature : T66BB85Valid, signed by author
Date : 2026-07-17T02:27:57+02:00

Updated transport node telemetry

Changes

4 files changed, 49 insertions(+), 32 deletions(-)


Diff

diff --git a/sbapp/sideband/console.py b/sbapp/sideband/console.py
index 5f65f3cf..1130308b 100644
--- a/sbapp/sideband/console.py
+++ b/sbapp/sideband/console.py
@@ -190,7 +190,7 @@ def attach(target_core, history_path=None):
_running = True
while _running:
if _context._stream_mode:
- print("[Log streaming active press, hit enter to return to console]")
+ print("[Log streaming active, press enter to return to console]")
_context.flush_log()
try: sys.stdin.readline()
except KeyboardInterrupt: pass

diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py
index 22300223..7ddd0c9a 100644
--- a/sbapp/sideband/core.py
+++ b/sbapp/sideband/core.py
@@ -681,6 +681,7 @@ class SidebandCore():
if not "trusted_markup_only" in self.config: self.config["trusted_markup_only"] = False
if not "compose_in_markdown" in self.config: self.config["compose_in_markdown"] = False
if not "confirm_calls" in self.config: self.config["confirm_calls"] = True
+ if not "notice_donation" in self.config: self.config["notice_donation"] = False
if not "input_language" in self.config: self.config["input_language"] = None
if not "allow_predictive_text" in self.config: self.config["allow_predictive_text"] = False

diff --git a/sbapp/sideband/sense.py b/sbapp/sideband/sense.py
index 8a24ea05..a443f4bb 100644
--- a/sbapp/sideband/sense.py
+++ b/sbapp/sideband/sense.py
@@ -3015,6 +3015,8 @@ class ConnectionMap(Sensor):
STALE_TIME = 60
DEFAULT_MAP_NAME = 0x00
+ POINT_STALE_TIME = 3*24*60*60
+
def __init__(self):
self.maps = {}
super().__init__(type(self).SID, type(self).STALE_TIME)
@@ -3030,22 +3032,19 @@ class ConnectionMap(Sensor):
map_name = self.DEFAULT_MAP_NAME
if not map_name in self.maps:
- self.maps[map_name] = {
- "name": map_name,
- "points": {},
- }
+ self.maps[map_name] = { "name": map_name,
+ "points": {} }
return self.maps[map_name]
def add_point(self, lat, lon, altitude=None, type_label=None, name=None, map_name=None,
signal_rssi=None, signal_snr=None, signal_q=None, hash_on_name_and_type_only=False):
- p = {
- "latitude": lat,
- "longitude": lon,
- "altitude": altitude,
- "type_label": type_label,
- "name": name}
+ p = {"latitude": lat,
+ "longitude": lon,
+ "altitude": altitude,
+ "type_label": type_label,
+ "name": name}
if not hash_on_name_and_type_only:
p_hash = RNS.Identity.truncated_hash(umsgpack.packb(p))
@@ -3053,41 +3052,46 @@ class ConnectionMap(Sensor):
p_hash = RNS.Identity.truncated_hash(umsgpack.packb({"type_label": type_label, "name": name}))
p["signal"] = {"rssi": signal_rssi, "snr": signal_snr, "q": signal_q}
+ p["added"] = time.time()
+
self.ensure_map(map_name)["points"][p_hash] = p
def update_data(self):
- self.data = {
- "maps": self.maps,
- }
+ self.data = { "maps": self.maps }
def pack(self):
+ now = time.time()
+ for m in self.maps:
+ sp = []
+ for p_hash in self.maps[m]["points"]:
+ p = self.maps[m]["points"][p_hash]
+ if now > p["added"]+self.POINT_STALE_TIME:
+ sp.append(p_hash)
+
+ for p_hash in sp:
+ try: self.maps[m]["points"].pop(p_hash)
+ except Exception as e: RNS.log(f"Could not remove stale point from connection map: {e}", RNS.LOG_DEBUG) # TODO: Remove
+
d = self.data
- if d == None:
- return None
+ if d == None: return None
else:
packed = self.data
return packed
def unpack(self, packed):
try:
- if packed == None:
- return None
- else:
- return packed
+ if packed == None: return None
+ else: return packed
- except:
- return None
+ except: return None
def render(self, relative_to=None):
- if self.data == None:
- return None
+ if self.data == None: return None
try:
- rendered = {
- "icon": "map-check-outline",
- "name": "Connection Map",
- "values": {"maps": self.data["maps"]},
- }
+ rendered = { "icon": "map-check-outline",
+ "name": "Connection Map",
+ "values": {"maps": self.data["maps"]} }
return rendered

diff --git a/sbapp/ui/objectdetails.py b/sbapp/ui/objectdetails.py
index 932a5cf6..910a0695 100644
--- a/sbapp/ui/objectdetails.py
+++ b/sbapp/ui/objectdetails.py
@@ -431,6 +431,7 @@ class RVDetails(MDRecycleView):
sort = {
"Information": 5,
"Timestamp": 7,
+ "Received": 9,
"Physical Link": 10,
"Location": 20,
"Ambient Light": 30,
@@ -451,7 +452,6 @@ class RVDetails(MDRecycleView):
"Tank": 90,
"Fuel": 91,
"Custom": 100,
- "Received": 200,
}
def pass_job(sender=None): pass
@@ -896,8 +896,20 @@ class RVDetails(MDRecycleView):
release_function = select
elif name == "Reticulum Transport":
- te = "enabled" if s["values"]["transport_enabled"] else "disabled"
- formatted_values = f"Reticulum Transport [b]{te}[/b]"
+ d = s["values"]
+ te = "enabled" if d["transport_enabled"] else "disabled"
+ ifc = d["interface_count"]; lnkc = d["link_count"]
+ upt = d["transport_uptime"]; mem = d["memory_used"]
+ rxb = d["traffic_rxb"]; txb = d["traffic_txb"]
+ rxs = d["speed_rx"]; txs = d["speed_tx"]
+ rxsi = d["speed_rx_inst"]; txsi = d["speed_tx_inst"]
+ pthc = len(d["path_table"])
+
+ formatted_values = f"Reticulum Transport [b]{te}[/b] with [b]{ifc}[/b] interface{'s' if ifc != 1 else ''}"
+ extra_entries.append({"icon": "routes", "text": f"[b]{pthc}[/b] destination{'s' if pthc != 1 else ''} reachable, [b]{lnkc}[/b] active link{'s' if lnkc != 1 else ''}"})
+ extra_entries.append({"icon": "clock-digital", "text": f"Up for [b]{RNS.prettytime(upt, compact=True)}[/b], using [b]{RNS.prettysize(mem)}[/b] RAM"})
+ extra_entries.append({"icon": "speedometer", "text": f"Throughput [b]{RNS.prettyspeed(rxs)}[/b] in, [b]{RNS.prettyspeed(txs)}[/b] out"})
+ extra_entries.append({"icon": "cube-send", "text": f"Traffic [b]{RNS.prettysize(rxb)}[/b] in, [b]{RNS.prettysize(txb)}[/b] out"})
elif name == "Connection Map":
mc = 0; pc = 0


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────